/**
 * @file risk.cpp
 * @brief 风险管理相关实现
 * @details 实现了风险管理器和持仓管理器的核心功能
 */

#include "risk/risk.h"
#include "market_data/market_data_types.h"
#include <algorithm>
#include <cmath>
#include <spdlog/spdlog.h>
#include <chrono>

namespace hft {

/**
 * @brief 默认风险管理器构造函�?
 * @param limits 风险限制参数
 * @details 初始化风险管理器的各项指标
 */
DefaultRiskManager::DefaultRiskManager(const RiskLimits& limits)
    : limits_(limits), mutex_(), metrics_()
{
    metrics_.current_drawdown = 0.0;    // 当前回撤
    metrics_.daily_pnl = 0.0;           // 当日盈亏
    metrics_.total_pnl = 0.0;           // 总盈亏
    metrics_.sharpe_ratio = 0.0;        // 夏普比率
    metrics_.max_drawdown = 0.0;        // 最大回撤
}

/**
 * @brief 检查订单是否满足风险限制
 * @param order 待检查的订单
 * @return 如果订单满足所有风险限制返回true，否则返回false
 */
bool DefaultRiskManager::checkOrder(const Order& order) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 检查全局风险限制
    if (!checkGlobalPositionLimit(order) ||    // 检查全局持仓限制
        !checkGlobalOrderSize(order) ||        // 检查全局订单规模
        !checkDrawdown() ||                    // 检查回撤限制
        !checkDailyLoss()) {                   // 检查日亏损限制
        return false;
    }
    
    // 检查合约特定的风险限制
    auto it = limits_.contract_limits.find(order.symbol);
    if (it != limits_.contract_limits.end()) {
        const auto& contract_limits = it->second;
        
        // 检查合约持仓限制
        auto pos_it = positions_.find(order.symbol);
        if (pos_it != positions_.end()) {
            const Position& pos = pos_it->second;
            double new_position_value = std::abs(pos.quantity + order.quantity) * order.price;
            if (new_position_value > contract_limits.max_position_value) {
                return false;
            }
        }
        
        // 检查合约订单规模限制
        double order_value = std::abs(order.quantity) * order.price;
        if (order_value > contract_limits.max_order_size) {
            return false;
        }
        
        // 检查合约杠杆
        double leverage = std::abs(order.quantity) * order.price / metrics_.total_pnl;
        if (leverage > contract_limits.max_leverage) {
            return false;
        }
    }
    
    return true;
}

/**
 * @brief 更新持仓信息
 * @param position 新的持仓信息
 * @details 更新持仓并重新计算相关风险指标
 */
void DefaultRiskManager::updatePosition(const Position& position) {
    std::lock_guard<std::mutex> lock(mutex_);
    positions_[position.symbol] = position;
    
    // 更新合约特定的风险指标
    double pnl = position.realized_pnl + position.unrealized_pnl;
    metrics_.contract_pnl[position.symbol] = pnl;
    
    // 更新合约回撤
    if (pnl < 0) {
        metrics_.contract_drawdown[position.symbol] = std::abs(pnl);
    } else {
        metrics_.contract_drawdown[position.symbol] = 0.0;
    }
    
    updateMetrics();
}

/**
 * @brief 更新盈亏信息
 * @param pnl 新的盈亏信息
 * @details 更新日盈亏和总盈亏，并重新计算风险指标
 */
void DefaultRiskManager::updatePnL(double pnl) {
    std::lock_guard<std::mutex> lock(mutex_);
    metrics_.daily_pnl += pnl;
    metrics_.total_pnl += pnl;
    updateMetrics();
}

/**
 * @brief 获取当前风险指标
 * @return 当前的风险指标数组
 */
RiskMetrics DefaultRiskManager::getRiskMetrics() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return metrics_;
}

/**
 * @brief 设置风险限制参数
 * @param limits 新的风险限制参数
 */
void DefaultRiskManager::setRiskLimits(const RiskLimits& limits) {
    std::lock_guard<std::mutex> lock(mutex_);
    limits_ = limits;
}

/**
 * @brief 设置特定合约的风险限制
 * @param symbol 合约代码
 * @param limits 合约特定的风险限制
 */
void DefaultRiskManager::setContractRiskLimits(const std::string& symbol, const ContractRiskLimits& limits) {
    std::lock_guard<std::mutex> lock(mutex_);
    limits_.contract_limits[symbol] = limits;
}

/**
 * @brief 检查全局持仓限制
 * @param order 待检查的订单
 * @return 如果满足持仓限制返回true，否则返回false
 */
bool DefaultRiskManager::checkGlobalPositionLimit(const Order& order) {
    double total_position_value = 0.0;
    for (const auto& pos : positions_) {
        total_position_value += std::abs(pos.second.quantity) * pos.second.average_price;
    }
    
    double new_position_value = std::abs(order.quantity) * order.price;
    return (total_position_value + new_position_value) <= limits_.max_position_value;
}

/**
 * @brief 检查全局订单规模限制
 * @param order 待检查的订单
 * @return 如果满足订单规模限制返回true，否则返回false
 */
bool DefaultRiskManager::checkGlobalOrderSize(const Order& order) {
    double order_value = std::abs(order.quantity) * order.price;
    return order_value <= limits_.max_order_size;
}

/**
 * @brief 检查回撤限制
 * @return 如果满足回撤限制返回true，否则返回false
 */
bool DefaultRiskManager::checkDrawdown() {
    return metrics_.current_drawdown <= limits_.max_drawdown;
}

/**
 * @brief 检查日亏损限制
 * @return 如果满足日亏损限制返回true，否则返回false
 */
bool DefaultRiskManager::checkDailyLoss() {
    return metrics_.daily_pnl >= -limits_.max_daily_loss;
}

/**
 * @brief 更新风险指标
 * @details 更新回撤和夏普比率等风险指标
 */
void DefaultRiskManager::updateMetrics() {
    // 更新回撤
    if (metrics_.total_pnl < 0) {
        metrics_.current_drawdown = std::abs(metrics_.total_pnl);
        metrics_.max_drawdown = std::max(metrics_.max_drawdown, metrics_.current_drawdown);
    } else {
        metrics_.current_drawdown = 0.0;
    }
    
    // 计算夏普比率（简化版本）
    // 在实际系统中，应该使用历史收益率数据
    metrics_.sharpe_ratio = metrics_.total_pnl / (metrics_.max_drawdown + 1e-6);
}

/**
 * @brief 持仓管理器构造函�?
 * @param risk_manager 风险管理器指针
 */
PositionManager::PositionManager(std::shared_ptr<RiskManager> risk_manager)
    : risk_manager_(risk_manager)
{}

/**
 * @brief 处理订单成交
 * @param order 成交的订单
 * @details 更新持仓信息并通知风险管理器
 */
void PositionManager::onOrderFilled(const Order& order) {
    std::lock_guard<std::mutex> lock(mutex_);
    updatePosition(order);
}

/**
 * @brief 处理订单取消
 * @param order 被取消的订单
 * @details 目前不需要特殊处理
 */
void PositionManager::onOrderCancelled(const Order& order) {
    // 取消订单不需要特殊处理
}

/**
 * @brief 获取特定合约的持仓信息
 * @param symbol 合约代码
 * @return 持仓信息，如果不存在则返回空持仓
 */
Position PositionManager::getPosition(const std::string& symbol) const {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = positions_.find(symbol);
    if (it == positions_.end()) {
        return Position{symbol, 0, 0.0, 0.0, 0.0};
    }
    return it->second;
}

/**
 * @brief 获取总盈亏
 * @return 所有持仓的总盈亏
 */
double PositionManager::getTotalPnL() const {
    std::lock_guard<std::mutex> lock(mutex_);
    double total_pnl = 0.0;
    for (const auto& pair : positions_) {
        total_pnl += pair.second.realized_pnl + pair.second.unrealized_pnl;
    }
    return total_pnl;
}

/**
 * @brief 更新持仓信息
 * @param order 成交的订单
 * @details 根据成交订单更新持仓信息，包括数量、均价和盈亏
 */
void PositionManager::updatePosition(const Order& order) {
    auto it = positions_.find(order.symbol);
    if (it == positions_.end()) {
        // 新建持仓
        Position pos;
        pos.symbol = order.symbol;
        pos.quantity = order.quantity;
        pos.average_price = order.price;
        pos.unrealized_pnl = 0.0;
        pos.realized_pnl = 0.0;
        positions_[order.symbol] = pos;
    } else {
        // 更新现有持仓
        Position& pos = it->second;
        int64_t new_quantity = pos.quantity + order.quantity;
        
        if (new_quantity == 0) {
            // 平仓
            double pnl = (order.price - pos.average_price) * pos.quantity;
            pos.realized_pnl += pnl;
            pos.quantity = 0;
            pos.average_price = 0.0;
            pos.unrealized_pnl = 0.0;
        } else {
            // 更新持仓
            pos.average_price = (pos.average_price * pos.quantity + order.price * order.quantity) / new_quantity;
            pos.quantity = new_quantity;
        }
    }
    
    // 更新风险管理器
    risk_manager_->updatePosition(positions_[order.symbol]);
}

RiskManager& RiskManager::getInstance() {
    static RiskManager instance;
    return instance;
}

bool RiskManager::init(const YAML::Node& config) {
    try {
        const auto& risk_config = config["trading"]["risk"];
        
        // 读取风控参数
        max_position_ = risk_config["max_position"].as<double>();
        max_margin_ratio_ = risk_config["max_margin_ratio"].as<double>();
        price_deviation_ = risk_config["price_deviation"].as<double>();
        max_orders_per_minute_ = risk_config["max_orders_per_minute"].as<int>();
        max_volatility_ = risk_config["max_volatility"].as<double>();

        spdlog::info("Risk manager initialized with parameters:");
        spdlog::info("Max position: {}", max_position_);
        spdlog::info("Max margin ratio: {}", max_margin_ratio_);
        spdlog::info("Price deviation: {}", price_deviation_);
        spdlog::info("Max orders per minute: {}", max_orders_per_minute_);
        spdlog::info("Max volatility: {}", max_volatility_);

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize risk manager: {}", e.what());
        return false;
    }
}

bool RiskManager::checkOrder(const Order& order) {
    // 检查持仓限制
    if (!checkPositionLimit(order)) {
        spdlog::warn("Order rejected by position limit: {}", order.order_id);
        return false;
    }

    // 检查资金限制
    if (!checkMarginLimit(order)) {
        spdlog::warn("Order rejected by margin limit: {}", order.order_id);
        return false;
    }

    // 检查价格限制
    if (!checkPriceLimit(order)) {
        spdlog::warn("Order rejected by price limit: {}", order.order_id);
        return false;
    }

    // 检查交易频率限制
    if (!checkFrequencyLimit(order)) {
        spdlog::warn("Order rejected by frequency limit: {}", order.order_id);
        return false;
    }

    // 检查波动率限制
    if (!checkVolatilityLimit(order)) {
        spdlog::warn("Order rejected by volatility limit: {}", order.order_id);
        return false;
    }

    return true;
}

void RiskManager::onMarketData(const MarketDataMessage& data) {
    // 更新价格数据
    auto& price_data = price_data_[data.symbol];
    price_data.prices.push_back(data.last_price);
    if (price_data.prices.size() > 100) { // 保留最近100个价格
        price_data.prices.erase(price_data.prices.begin());
    }

    // 更新最高最低价
    if (data.last_price > price_data.high) {
        price_data.high = data.last_price;
    }
    if (data.last_price < price_data.low || price_data.low == 0) {
        price_data.low = data.last_price;
    }

    // 更新收盘价
    price_data.close = data.last_price;
}

void RiskManager::onTrade(const Trade& trade) {
    // 记录交易
    TradeRecord record;
    record.timestamp = trade.timestamp;
    record.symbol = trade.symbol;
    record.price = trade.price;
    record.volume = trade.volume;
    trade_records_.push_back(record);

    // 清理过期交易记录
    auto now = std::chrono::system_clock::now();
    trade_records_.erase(
        std::remove_if(trade_records_.begin(), trade_records_.end(),
            [now](const TradeRecord& record) {
                return (now - record.timestamp) > std::chrono::minutes(1);
            }),
        trade_records_.end()
    );
}

void RiskManager::onPosition(const Position& position) {
    positions_[position.symbol] = position;
}

void RiskManager::onAccount(const Account& account) {
    account_ = account;
}

YAML::Node RiskManager::getParams() const {
    YAML::Node params;
    params["max_position"] = max_position_;
    params["max_margin_ratio"] = max_margin_ratio_;
    params["price_deviation"] = price_deviation_;
    params["max_orders_per_minute"] = max_orders_per_minute_;
    params["max_volatility"] = max_volatility_;
    return params;
}

bool RiskManager::setParams(const YAML::Node& params) {
    try {
        if (params["max_position"]) {
            max_position_ = params["max_position"].as<double>();
        }
        if (params["max_margin_ratio"]) {
            max_margin_ratio_ = params["max_margin_ratio"].as<double>();
        }
        if (params["price_deviation"]) {
            price_deviation_ = params["price_deviation"].as<double>();
        }
        if (params["max_orders_per_minute"]) {
            max_orders_per_minute_ = params["max_orders_per_minute"].as<int>();
        }
        if (params["max_volatility"]) {
            max_volatility_ = params["max_volatility"].as<double>();
        }
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to set parameters: {}", e.what());
        return false;
    }
}

bool RiskManager::checkPositionLimit(const Order& order) {
    auto it = positions_.find(order.symbol);
    if (it == positions_.end()) {
        return order.volume <= max_position_;
    }

    const Position& position = it->second;
    double current_position = order.direction == OrderDirectionType::BUY ? 
        position.long_volume : position.short_volume;
    
    if (order.offset == OrderOffset::OPEN) {
        return current_position + order.volume <= max_position_;
    } else {
        return current_position >= order.volume;
    }
}

bool RiskManager::checkMarginLimit(const Order& order) {
    double required_margin = order.price * order.volume * 0.1; // 假设保证金比例为10%
    double total_margin = account_.margin + required_margin;
    double margin_ratio = total_margin / account_.balance;
    return margin_ratio <= max_margin_ratio_;
}

bool RiskManager::checkPriceLimit(const Order& order) {
    auto it = price_data_.find(order.symbol);
    if (it == price_data_.end()) {
        return true;
    }

    const PriceData& price_data = it->second;
    double last_price = price_data.close;
    double deviation = std::abs(order.price - last_price) / last_price;
    return deviation <= price_deviation_;
}

bool RiskManager::checkFrequencyLimit(const Order& order) {
    auto now = std::chrono::system_clock::now();
    int order_count = std::count_if(trade_records_.begin(), trade_records_.end(),
        [now](const TradeRecord& record) {
            return (now - record.timestamp) <= std::chrono::minutes(1);
        });
    return order_count < max_orders_per_minute_;
}

bool RiskManager::checkVolatilityLimit(const Order& order) {
    // 检查熔断状态
    if (is_circuit_breaker_triggered_) {
        spdlog::warn("Order {} rejected due to circuit breaker", order.order_id);
        return false;
    }

    double volatility = calculateVolatility(order.symbol);
    bool is_valid = volatility <= max_volatility_;

    // 检查是否需要触发熔断
    if (!is_valid && !is_circuit_breaker_triggered_) {
        triggerCircuitBreaker();
    }

    return is_valid;
}

void RiskManager::triggerCircuitBreaker() {
    std::lock_guard<std::mutex> lock(circuit_mutex_);
    if (!is_circuit_breaker_triggered_) {
        is_circuit_breaker_triggered_ = true;
        circuit_trigger_time_ = std::chrono::system_clock::now();
        spdlog::error("Circuit breaker triggered due to high volatility");
        
        // 启动恢复检查线程
        recovery_thread_ = std::thread([this]() {
            while (is_circuit_breaker_triggered_) {
                std::this_thread::sleep_for(std::chrono::seconds(10));
                
                // 检查是否可以恢复
                bool can_recover = true;
                for (auto& pair : price_data_) {
                    double vol = calculateVolatility(pair.first);
                    if (vol > max_volatility_ * 0.8) { // 波动率降到阈值的80%才恢复
                        can_recover = false;
                        break;
                    }
                }
                
                if (can_recover) {
                    std::lock_guard<std::mutex> lock(circuit_mutex_);
                    is_circuit_breaker_triggered_ = false;
                    spdlog::info("Circuit breaker recovered");
                }
            }
        });
        recovery_thread_.detach();
    }
}

double RiskManager::calculateVolatility(const std::string& symbol) {
    // 检查缓存
    auto now = std::chrono::system_clock::now();
    auto cache_it = volatility_cache_.find(symbol);
    if (cache_it != volatility_cache_.end() && 
        (now - cache_it->second.timestamp) < std::chrono::seconds(5)) {
        return cache_it->second.value;
    }

    auto it = price_data_.find(symbol);
    if (it == price_data_.end() || it->second.prices.size() < 2) {
        return 0.0;
    }

    const std::vector<double>& prices = it->second.prices;
    size_t n = prices.size();
    
    // 使用Welford算法在线计算方差，提高数值稳定性
    double mean = 0.0;
    double M2 = 0.0;
    for (size_t i = 1; i < n; ++i) {
        double ret = (prices[i] - prices[i-1]) / prices[i-1];
        double delta = ret - mean;
        mean += delta / i;
        M2 += delta * (ret - mean);
    }

    double variance = n > 1 ? M2 / (n - 1) : 0.0;
    double volatility = std::sqrt(variance) * std::sqrt(252.0);

    // 更新缓存
    volatility_cache_[symbol] = {volatility, now};

    return volatility;
}

} // namespace hft 